package cn.cqs.redisitem.utils.AES;

import io.jsonwebtoken.*;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

public class JwtUtils {
    private static Long ttlMillis;

    /**
     * 功能描述 :
     *
     * @param userid:用户ID
     * @param userName:用户名
     * @return java.lang.String
     * @author cqs
     * @date 2020/9/11
     */

    public static String generateJWT(String userid, String userName) {
//        申明算法为HS512
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;
        //密钥
        SecretKey secretKey = generalKey();
        Long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
//       生成token 通过jwts.builder（）生成JwtBuilder对象，再通过JwtBuilder对象的compact()方法生成token
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId(userid)
                .setSubject(userName)
                .setIssuer("user")
                .setIssuedAt(now)
                .signWith(signatureAlgorithm, secretKey)
                .claim("role", "admin");

        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            // 过期时间
            jwtBuilder.setExpiration(expDate).setNotBefore(now);
        }
        return jwtBuilder.compact();
    }

    /**
     * 功能描述 :生成密钥
     * @author cqs
     * @date 2020/9/11

     * @return javax.crypto.SecretKey
     */

    private static SecretKey generalKey() {
        //1. String 类型 转 Byte数值：String.getBytes()
        byte[] byetes = SystemConstant.JWT_SECERT.getName().getBytes();
        String key = SystemConstant.JWT_SECERT.getName();
//       2. String类型 转 Char数组：String.toCharArray()
        char[] chars = key.toCharArray();
        byte[] encodeKey = Base64Utils.decode(chars);
//        根据一个字节数组构造一个 SecretKey，而无须通过一个（基于 provider 的）SecretKeyFactory
        SecretKey secretKey = new SecretKeySpec(encodeKey, 0, encodeKey.length, "AES");
        return secretKey;
    }

    /**
     * 验证JWT
     */

    public static CheckResult validateJWT(String token) {
        CheckResult checkResult = new CheckResult();
        Claims claims = null;
        try {
            claims = parseJWT(token);
            if (claims != null) {
                checkResult.setSuccess(true);
                checkResult.setClaims(claims);
            }
        } catch (ExpiredJwtException e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_EXPIRE.getName());
            checkResult.setSuccess(false);
        } catch (SignatureException e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL.getName());
            checkResult.setSuccess(false);
        } catch (Exception e) {
            checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL.getName());
            checkResult.setSuccess(false);
        }
        return checkResult;
    }


    /**
     * 解析token
     *
     * @param token
     * @return
     */
    private static Claims parseJWT(String token) throws Exception {
//       获取 密钥即盐
        SecretKey secretKey = generalKey();
//        解析token 使用Jwts.parser（）方法生成Claims对象
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody();
        return claims;
    }
    /**
     * 功能描述 :获取失效时间
     * @author cqs
     * @date 2020/9/11
     * @param token:
     * @return java.util.Date
     */

    public static Date getExpairtion(String token) throws Exception{
            Claims claims=parseJWT(token);
            Date expration=claims.getExpiration();
        return expration;
    }


    public static void main(String[] args) {
//      String token=  generateJWT ("aa","cqs",20000000);
//        System.out.println(token);
//        Claims claims = null;
//        try {
//            claims = parseJWT(token);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        System.out.println("用户ID:"+claims.getId()+"\t用户名："+claims.getSubject()+"\t失效时间"+
//                new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(claims.getExpiration())
//                +"角色："+claims.get("role")
//        );
//        System.out.println(validateJWT(token));
    }
}